/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.aliang.jp.jp;

import java.awt.Point;
import java.awt.Rectangle;
import java.awt.event.MouseEvent;

/**
 * 状态的基类，同时也负责进行状态管理
 * @author liuruile
 */
public abstract class State {

    // 前面这几个static的方法用变量，是进行状态管理时用的
    private static SelectedState selectedState = new SelectedState(); // 选择状态
    private static ModifyState modifyState = new ModifyState(); // 修改状态
    public static State currentState = selectedState; // 当前状态

    protected static State getSelectState() {
        return selectedState;
    }

    protected static State getModifyState(){
        return modifyState;
    }

    /**
     * 用来改变状态，将当前状态由from状态变为to状态
     * @param from 原来的状态
     * @param to 变迁后的状态
     */
    protected static void changeState(State from , State to) {
        to.setStateParent(from.parent);
        to.start = from.start;
        to.end = from.end;
        currentState = to;
    }

    // 下面是状态相关的方法及变量
    protected Point start,  end;
    private int dragRectWidth = 8;
    protected ScreenFrame parent;

    public abstract void mouseMoved(MouseEvent e);

    public abstract void mousePressed(MouseEvent e);

    public abstract void mouseClicked(MouseEvent e);

    public abstract void mouseReleased(MouseEvent e);

    public abstract void mouseDragged(MouseEvent e);

    /**
     * 设置状态的执有者，表示当前状态对象的归属
     * @param parent 执有者
     */
    public void setStateParent(ScreenFrame parent) {
        this.parent = parent;
    }

    /**
     * 获取选择的矩形
     * @return 选择的矩形
     */
    public Rectangle getSelectedRect() {
        if (start == null || end == null) {
            return null;
        }
        int x = start.x <= end.x ? start.x : end.x;
        int y = start.y <= end.y ? start.y : end.y;
        Rectangle rct = null;
        if (!invaildRectangle()) {
            rct = new Rectangle(x, y, Math.abs(end.x - start.x),
                    Math.abs(end.y - start.y));
        }
        return rct;
    }

    /**
     * 获取8个方向调整矩形，其顺序为（NW, N, NE, E, SE, S, SW, W）
     * @return 大小为8的矩形数组
     */
    public Rectangle[] getCornerRects() {
        Rectangle[] corners = new Rectangle[8];
        int x = start.x <= end.x ? start.x : end.x;
        int y = start.y <= end.y ? start.y : end.y;
        int i = 0;
        corners[i++] = new Rectangle(x - dragRectWidth / 2, y - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x + Math.abs(end.x - start.x)/2 - dragRectWidth / 2, y - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x + Math.abs(end.x - start.x) - dragRectWidth / 2, y - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x + Math.abs(end.x - start.x) - dragRectWidth / 2, y + Math.abs(end.y - start.y)/2 - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x + Math.abs(end.x - start.x) - dragRectWidth / 2, y + Math.abs(end.y - start.y) - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x + Math.abs(end.x - start.x)/2 - dragRectWidth / 2, y + Math.abs(end.y - start.y) - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x - dragRectWidth / 2, y + Math.abs(end.y - start.y) - dragRectWidth / 2, dragRectWidth, dragRectWidth);
        corners[i++] = new Rectangle(x - dragRectWidth / 2, y + Math.abs(end.y - start.y)/2 - dragRectWidth / 2, dragRectWidth, dragRectWidth);

        return corners;
    }

    /**
     * 矩形是否非法
     * @return true--非法 false--合法
     */
    private boolean invaildRectangle() {
        return Math.abs(end.x - start.x) <= 0 || Math.abs(end.y - start.y) <= 0;
    }
}
